package org.javarosa.core.services.properties.mesh4j.extensions;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.javarosa.core.JavaRosaServiceProvider;
import org.javarosa.core.services.properties.IPropertyRules;
import org.javarosa.core.services.transport.TransportMessage;

public class Mesh4jPropertyRules implements IPropertyRules{

	// CONSTANTS
	public static final String HTTP_SYNC_BASE_URL = "Mesh4xBaseUrl";
	public static final String HTTP_DISCOVERY_XFORMS_URL = "Mesh4xDiscoveryUrl";
	public static final String SMS_DEFAULT_TARGET = "Mesh4xDefaultSmsTarget";
	public static final String SMS_PORT = "Mesh4xDefaultSmsPort";
	public static final String SMS_BLOCK_DIFF_SIZE = "Mesh4xBlockDiffSize";
	public static final String SMS_MAX_MESSAGE_LENGHT = "Mesh4xMaxMessageLenght";

	public static final String SMS_RECEIVER_RETRY_TIMEOUT = "Mesh4xReceiverRetryTimeOut";
	public static final String SMS_SENDER_RETRY_TIMEOUT = "Mesh4xSenderRetryTimeOut";
	public static String TIMEOUT_NO = "no";
	public static String TIMEOUT_1_MINUTE = "1 min";
	public static String TIMEOUT_5_MINUTE = "5 min";
	public static String TIMEOUT_10_MINUTE = "10 min";
	public static String TIMEOUT_15_MINUTE = "15 min";
	public static String TIMEOUT_30_MINUTE = "30 min";
	public static String TIMEOUT_1_HOUR = "1 hs";
	public static String TIMEOUT_6_HOUR = "6 hs";
	public static String TIMEOUT_12_HOUR = "12 hs";
	
	public static final String USE_TEMPLATES = "Mesh4xUseTemplates";
	public static final String USE_TEMPLATES_YES = "yes";
	public static final String USE_TEMPLATES_NO = "no";
	
	// MODEL VARIABLES
    private Hashtable rules;
    private Vector readOnlyProperties;
	
    // BUSINESS METHODS
    public Mesh4jPropertyRules() {
    	
        this.rules = new Hashtable();
        this.readOnlyProperties = new Vector();

        this.rules.put(HTTP_SYNC_BASE_URL, new Vector());
        this.rules.put(HTTP_DISCOVERY_XFORMS_URL, new Vector());
        this.rules.put(SMS_DEFAULT_TARGET, new Vector());
        this.rules.put(SMS_PORT, new Vector());
        this.rules.put(SMS_BLOCK_DIFF_SIZE, new Vector());
        this.rules.put(SMS_MAX_MESSAGE_LENGHT, new Vector());

        Vector allowableTimeOutValues = new Vector();
        allowableTimeOutValues.addElement(TIMEOUT_NO);
        allowableTimeOutValues.addElement(TIMEOUT_1_MINUTE);
        allowableTimeOutValues.addElement(TIMEOUT_5_MINUTE);
        allowableTimeOutValues.addElement(TIMEOUT_10_MINUTE);
        allowableTimeOutValues.addElement(TIMEOUT_15_MINUTE);
        allowableTimeOutValues.addElement(TIMEOUT_30_MINUTE);
        allowableTimeOutValues.addElement(TIMEOUT_1_HOUR);
        allowableTimeOutValues.addElement(TIMEOUT_6_HOUR);
        allowableTimeOutValues.addElement(TIMEOUT_12_HOUR);
        
        this.rules.put(SMS_RECEIVER_RETRY_TIMEOUT, allowableTimeOutValues);
        this.rules.put(SMS_SENDER_RETRY_TIMEOUT, allowableTimeOutValues);
        
        
        Vector allowableUseTemplateValues = new Vector();
        allowableUseTemplateValues.addElement(USE_TEMPLATES_YES);
        allowableUseTemplateValues.addElement(USE_TEMPLATES_NO);
        this.rules.put(USE_TEMPLATES, allowableUseTemplateValues);
    }

    public Vector allowableValues(String propertyName) {
        return (Vector)rules.get(propertyName);
    }

    public boolean checkValueAllowed(String propertyName, String potentialValue) {
        Vector prop = ((Vector)rules.get(propertyName));
        if(prop.size() != 0) {
            //Check whether this is a dynamic property
            if(prop.size() == 1 && checkPropertyAllowed((String)prop.elementAt(0))) {
                // If so, get its list of available values, and see whether the potentival value is acceptable.
                return ((Vector)JavaRosaServiceProvider.instance().getPropertyManager().getProperty((String)prop.elementAt(0))).contains(potentialValue);
            }
            else {
                return ((Vector)rules.get(propertyName)).contains(potentialValue);
            }
        }
        else
            return true;
    }

    public Vector allowableProperties() {
        Vector propList = new Vector();
        Enumeration iter = rules.keys();
        while (iter.hasMoreElements()) {
            propList.addElement(iter.nextElement());
        }
        return propList;
    }

    public boolean checkPropertyAllowed(String propertyName) {
        Enumeration iter = rules.keys();
        while (iter.hasMoreElements()) {
            if(propertyName.equals(iter.nextElement())) { 
                return true;
            }
        }
        return false;
    }
    
    public boolean checkPropertyUserReadOnly(String propertyName){
        return readOnlyProperties.contains(propertyName);
    }

	public static String getSmsPor() {
		return JavaRosaServiceProvider.instance().getPropertyManager().getSingularProperty(SMS_PORT);
	}

	public static int getBlockDiff() {
		return Integer.valueOf(JavaRosaServiceProvider.instance().getPropertyManager().getSingularProperty(SMS_BLOCK_DIFF_SIZE));
	}

	public static int getMaxMessageLenght() {
		return Integer.valueOf(JavaRosaServiceProvider.instance().getPropertyManager().getSingularProperty(SMS_MAX_MESSAGE_LENGHT));
	}
	
	public static int getReceiverRetryTimeOut() {
		return getTimeOut(JavaRosaServiceProvider.instance().getPropertyManager().getSingularProperty(SMS_RECEIVER_RETRY_TIMEOUT));
	}

	public static int getSenderRetryTimeOut() {
		return getTimeOut(JavaRosaServiceProvider.instance().getPropertyManager().getSingularProperty(SMS_SENDER_RETRY_TIMEOUT));
	}

	private static int getTimeOut(String timeOutOption) {
		int timeOut = 0;  // TIMEOUT_NO
		if(TIMEOUT_1_MINUTE.equals(timeOutOption)){
			timeOut = 1 * 60 * 1000;
		} else if(TIMEOUT_5_MINUTE.equals(timeOutOption)){
			timeOut = 5 * 60 * 1000;
		} else if(TIMEOUT_10_MINUTE.equals(timeOutOption)){
			timeOut = 10 * 60 * 1000;
		} else if(TIMEOUT_15_MINUTE.equals(timeOutOption)){
			timeOut = 15 * 60 * 1000;
		} else if(TIMEOUT_30_MINUTE.equals(timeOutOption)){
			timeOut = 30 * 60 * 1000;
		} else if(TIMEOUT_1_HOUR.equals(timeOutOption)){
			timeOut = 1 * 60 * 60 * 1000;
		} else if(TIMEOUT_6_HOUR.equals(timeOutOption)){
			timeOut = 6 * 60 * 60 * 1000;
		} else if(TIMEOUT_12_HOUR.equals(timeOutOption)){
			timeOut = 12 * 60 * 60 * 1000;
		} 
		return timeOut;
	}

	public String getHumanReadableDescription(String propertyName) {
		//TODO: Jazz this up with some decorated descriptions
		return propertyName;
	}

	public String getHumanReadableValue(String propertyName, String value) {
		//TODO: Jazz this up with some decorated descriptions
		return value;
	}

	public void handlePropertyChanges(String propertyName) {
		// Nothing (yet).
	}


}
